﻿using System;
using System.Collections.Generic; 
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Ether.Libs;

namespace Ether.Mapping
{
    public class Cell : ISelectable
    {
        //Fields
        public LevelMap ParentMap;
        public CellPrim MyPrim;
        public CellType MyType;
        public CellTextureType MyTexture;

        public EtherPosition MyEtherPosition;
        public SelectionGridMode SelectionMode { get; internal set; }

        public Structure Structure {get; set; }
        public bool BuildAvaliable;

        //Construct 
        public Cell(LevelMap ParentMap, int level, Vector2 mapPosition, CellType type,
            CellTextureType texture, CellRotation Rotation)
        {
            this.ParentMap = ParentMap;
            this.MyType = type;
            this.MyTexture = texture;

            MyEtherPosition = EtherPosition.FromMapPosition(mapPosition, level);
            MyPrim = new CellPrim(MyEtherPosition.ToWorldSpace(), MyEtherPosition.S, MyType, Rotation);
        }

        //Methods
        private void RenderBuildMode(Effect fx)
        {
            //during the build phase we always show the selection grid
            fx.Parameters["ShowSelection"].SetValue(true);

            //in the build state cell is always white unless we are in placement mode
            Vector4 sColor = EtherEngine.SelectionWhite.ToVector4();

            switch (SelectionMode)
            {
                case SelectionGridMode.White:
                case SelectionGridMode.None:
                    break;

                case SelectionGridMode.Red: sColor = EtherEngine.SelectionRed.ToVector4(); break;
                case SelectionGridMode.Green: sColor = EtherEngine.SelectionGreen.ToVector4(); break;
            }

            fx.Parameters["SelectionGridColor"].SetValue(sColor);
            fx.Parameters["Hover"].SetValue((SelectState != SelectionState.None));
        }
        private void RenderCombatMode(Effect fx)
        {
            fx.Parameters["ShowSelection"].SetValue((SelectState != SelectionState.None));

            Vector4 sColor = EtherEngine.SelectionWhite.ToVector4();

            switch (SelectionMode)
            {
                case SelectionGridMode.White:
                case SelectionGridMode.None:
                    break;

                case SelectionGridMode.Red: sColor = EtherEngine.SelectionRed.ToVector4(); break;
                case SelectionGridMode.Green: sColor = EtherEngine.SelectionGreen.ToVector4(); break;
            }

            fx.Parameters["SelectionGridColor"].SetValue(sColor);

            fx.Parameters["Hover"].SetValue((SelectState != SelectionState.None));
        }

        public void SetTextureType(CellTextureType cellTextureType)
        {
            MyTexture = cellTextureType;
        }
        public void SetSelectionGridMode(SelectionGridMode mode)
        {
            SelectionMode = mode;
        }
        public void SetRotation(CellRotation Rotation)
        {
            this.MyPrim.SetRotation(Rotation);
        }

        public void DebugRenderCell(DebugDrawer dDrawer)
        {
            dDrawer.DrawAabb(MyPrim.BoundingBox.Min, MyPrim.BoundingBox.Max, Color.Red);

            if (Structure != null) 
                dDrawer.DrawAabb(Structure.Body.BoundingBox.Min, Structure.Body.BoundingBox.Max, Color.Blue);
        }
        public void RenderCell(Camera camera, GameTime time)
        {
            if(MyType == CellType.None)
                return; //NOTHING TO DRAW 
            int number = (MyType == CellType.Normal || MyType == CellType.Solid) ? 0 : 1;
            Model mtu = Resources.TileModels[number];

            Matrix[] transforms = new Matrix[mtu.Bones.Count];
            mtu.CopyAbsoluteBoneTransformsTo(transforms);

            foreach (ModelMesh mesh in mtu.Meshes)
            {
                foreach (Effect fx in mesh.Effects)
                {
                    fx.CurrentTechnique = fx.Techniques["CellShade"];
                    fx.Parameters["World"].SetValue(transforms[mesh.ParentBone.Index] * MyPrim.World);
                    fx.Parameters["View"].SetValue(camera.View);
                    fx.Parameters["Projection"].SetValue(camera.Projection);

                    fx.Parameters["CellTexture"].SetValue(Resources.TileTextures[(int)MyTexture + ((MyType == CellType.Ramp) ? 3 : 0)]);
                    fx.Parameters["SelectionIndicator"].SetValue(Resources.SelectionGrids[number]);
                    fx.Parameters["HoverHeight"].SetValue(EtherEngine.HoverHeight);

                    fx.Parameters["AmbientColor"].SetValue(EtherEngine.AmbientColor);
                    fx.Parameters["AmbientLevel"].SetValue(EtherEngine.AmbientLevel);

                    //fx.Parameters["DiffuseDirection"].SetValue(EtherEngine.DiffuseDirection);
                    //fx.Parameters["DiffuseColor"].SetValue(EtherEngine.DiffuseColor);
                    //fx.Parameters["DiffuseLevel"].SetValue(EtherEngine.DiffuseLevel);

                    RenderCombatMode(fx);
                    //RenderBuildMode(fx);
                }
                mesh.Draw();
            }

            if (Structure != null)
                Structure.DrawStructure(camera, time);

        }
        public void UpdateCell(GameTime time)
        {
            return; // NOTHING TODO
        }
        
        //ISelectable
        #region ### ISelectableStuff ###

        public Jitter.Dynamics.RigidBody Body
        {
            get { return MyPrim; }
        }
        public SelectionState SelectState
        {
            get;
            set;
        }
        public EtherPosition Position
        {
            get { return MyEtherPosition; }
        }

        #endregion                
    }
}
